package com.gtcmu.skeye;

import java.io.IOException;
import java.util.List;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

class Preview extends SurfaceView implements SurfaceHolder.Callback {
	SurfaceHolder mHolder;
	Camera mCamera;
	private final static String DEBUG_TAG = "Preview";
	
	void init()
	{
		// Install a SurfaceHolder.Callback so we get notified when the
		// underlying surface is created and destroyed.
		mHolder = getHolder();
		mHolder.addCallback(this);
		mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		
		try {
			mCamera.setPreviewDisplay(mHolder);
			mCamera.startPreview();
		} catch (IOException e) {
			mCamera.release();
			mCamera = null;
			Log.d(DEBUG_TAG,"surfaceCreated -- Could not start preview: "+ e.getMessage());
			// TODO: add more exception handling logic here
		}
	}
	
	public Preview(Context context, Camera camera) {
		super(context);

		this.mCamera = camera;
		init();
	}
	
	/*public Preview(Context context)
    {
        super(context);
        //init();
    }
    public Preview(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        //init();
    }
    public Preview(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        //init();
    }*/

	public void surfaceCreated(SurfaceHolder holder) {
		// The Surface has been created, acquire the camera and tell it where
		// to draw.
		//mCamera = Camera.open();
		Log.d(DEBUG_TAG,"surfaceCreated ");
		try {
			mCamera.setPreviewDisplay(holder);
			mCamera.startPreview();
		} catch (IOException e) {
			mCamera.release();
			mCamera = null;
			Log.d(DEBUG_TAG,"surfaceCreated -- Could not start preview: "+ e.getMessage());
			// TODO: add more exception handling logic here
		}
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		// Surface will be destroyed when we return, so stop the preview.
		// Because the CameraDevice object is not a shared resource, it's very
		// important to release it when the activity is paused.
		Log.d(DEBUG_TAG,"surfaceDestroyed ");
		if(mCamera != null)
		{
			mCamera.stopPreview();
			mCamera.release();
			mCamera = null;
		}
	}

	private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
		final double ASPECT_TOLERANCE = 0.05;
		double targetRatio = (double) w / h;
		if (sizes == null)
			return null;

		Size optimalSize = null;
		double minDiff = Double.MAX_VALUE;

		int targetHeight = h;

		// Try to find an size match aspect ratio and size
		for (Size size : sizes) {
			double ratio = (double) size.width / size.height;
			if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
				continue;
			if (Math.abs(size.height - targetHeight) < minDiff) {
				optimalSize = size;
				minDiff = Math.abs(size.height - targetHeight);
			}
		}

		// Cannot find the one match the aspect ratio, ignore the requirement
		if (optimalSize == null) {
			minDiff = Double.MAX_VALUE;
			for (Size size : sizes) {
				if (Math.abs(size.height - targetHeight) < minDiff) {
					optimalSize = size;
					minDiff = Math.abs(size.height - targetHeight);
				}
			}
		}
		return optimalSize;
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		// Now that the size is known, set up the camera parameters and begin
		// the preview.
		Log.d(DEBUG_TAG,"surfaceChanged ");			
		if(mHolder.getSurface() == null)
		{
			
			Log.d(DEBUG_TAG,"surfaceChanged mHolder.getSurface() == null");
			return;
		}
		
		try{
			mCamera.stopPreview();
		}catch(Exception e)
		{}
		
		try
		{
			Camera.Parameters parameters = mCamera.getParameters();
	
			List<Size> sizes = parameters.getSupportedPreviewSizes();
			Size optimalSize = getOptimalPreviewSize(sizes, w, h);
			parameters.setPreviewSize(optimalSize.width, optimalSize.height);
			mCamera.setParameters(parameters);
			mCamera.setPreviewDisplay(mHolder);
			mCamera.startPreview();
		}catch(Exception e)
		{
			Log.d(DEBUG_TAG,"surfaceChanged -- Could not start preview: "+ e.getMessage());
		}
	}

}
